package org.tczs93.springsecurity.config.security;

import com.mysql.cj.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.tczs93.springsecurity.config.exception.CustomerException;
import org.tczs93.springsecurity.mapper.TokenMapper;
import org.tczs93.springsecurity.model.Token;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;

/**
 * @author ：tao.li
 * @description：token认证
 * @date ：Created in 2021/8/28 14:56
 */
@Component
public class TokenAuthenticationFilter extends OncePerRequestFilter  {

    private static final String tokenHead = "Bearer ";
    private static final String tokenHeader = "Authorization";

    @Autowired
    private TokenMapper tokenMapper;

    @Autowired
    private UserDetailsService userDetailsService;

    /**
     * token filter.
     *
     * @param request     .
     * @param response    .
     * @param filterChain .
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request,HttpServletResponse response,FilterChain filterChain)
            throws ServletException, IOException,CustomerException {
        String authHeader = request.getHeader(this.tokenHeader);
        if (authHeader != null && authHeader.startsWith(tokenHead)) {
            String authToken = authHeader.substring(tokenHead.length()); // The part after "Bearer "
            if (StringUtils.isNullOrEmpty(authToken))
                throw new CustomerException("token已失效");
            Token token = tokenMapper.findByToken(authToken);
            if(token == null)
                throw new CustomerException("token已失效");
            if (SecurityContextHolder.getContext().getAuthentication() == null) {
                //手动构建一个user,密码不需要
                User user = new User(token.getUserName(),"", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));
                //下面几行效果是将用户信息存储到当前线程中
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                        user, null, AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }
        filterChain.doFilter(request, response);
    }

}
